package com.spddr.pmos.oauth2;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.cxf.rs.security.oauth2.common.Client;
import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
import org.apache.cxf.rs.security.oauth2.common.UserSubject;
import org.apache.cxf.rs.security.oauth2.provider.AbstractOAuthDataProvider;
import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.spddr.pmos.repos.UserRepos;

@Service
public class Oauth2DataProviderImpl extends AbstractOAuthDataProvider {
	private final Cache<String, Client> clients = buildCache(256, 5);
	private final Cache<String, ServerAccessToken> accessTokens = buildCache(1024, 1440);
	private final Cache<String, RefreshToken> refreshTokens = buildCache(1024, 1440 * 7);

	@Autowired
	private UserRepos userRepos;

	@Override
	public Client getClient(final String clientId) throws OAuthServiceException {
		Client client = clients.getIfPresent(clientId);

		if (null == client) {
			client = loadClient(clientId);
		}

		return client;
	}

	private Client loadClient(final String clientId) {
		return null;
		// User entity = userRepos.findByUsernameIgnoringCase(clientId);
		// if (null == entity || Boolean.TRUE.equals(entity.isDisable())) { return null; }
		//
		// //username == client_id
		// Client client = new Client(entity.getUsername(), entity.getPassword(), true);
		//
		// UserSubject subject = new UserSubject(entity.getUsername(), entity.getId().toString());
		// subject.setRoles(Lists.transform(entity.getRoles(), new Function<Role, String>() {
		// @Override
		// public String apply(Role input) {
		// return input.getName();
		// }
		// }));
		// client.setSubject(subject);
		//
		// Set<String> permissions = new HashSet<>();
		// for (Role role : entity.getRoles()) {
		// for (Permission permission : role.getPermissions()) {
		// permissions.add(permission.getName());
		// }
		// }
		// client.setRegisteredScopes(new ArrayList<>(permissions));
		//
		// clients.put(clientId, client);
		//
		// return client;
	}

	private static <K, V> Cache<K, V> buildCache(int maxSize, int expire) {
		return CacheBuilder.newBuilder()
				.maximumSize(maxSize)
				.expireAfterAccess(expire, TimeUnit.MINUTES)
				.build();
	}

	@Override
	public ServerAccessToken getAccessToken(String accessToken) throws OAuthServiceException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<ServerAccessToken> getAccessTokens(Client client, UserSubject subject) throws OAuthServiceException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<RefreshToken> getRefreshTokens(Client client, UserSubject subject) throws OAuthServiceException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setClient(Client client) {
		// TODO Auto-generated method stub

	}

	@Override
	public List<Client> getClients(UserSubject resourceOwner) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected void saveAccessToken(ServerAccessToken serverToken) {
		// TODO Auto-generated method stub

	}

	@Override
	protected void saveRefreshToken(RefreshToken refreshToken) {
		// TODO Auto-generated method stub

	}

	@Override
	protected void doRevokeAccessToken(ServerAccessToken accessToken) {
		// TODO Auto-generated method stub

	}

	@Override
	protected void doRevokeRefreshToken(RefreshToken refreshToken) {
		// TODO Auto-generated method stub

	}

	@Override
	protected RefreshToken getRefreshToken(String refreshTokenKey) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected void doRemoveClient(Client c) {
		// TODO Auto-generated method stub

	}
}
